﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BLL;
using BTO;
using Exceptions;

namespace CentralReserva
{
    public class MenuCategoriasAlojamento
    {
        private static int opcao = 0;

        public static void menuCategoriasAlojamento()
        {
            do
            {
                Console.WriteLine("Menu Categorias de Alojamento: Escolha uma das opçoes disponiveis.\n\n");
                Console.WriteLine(" 1 - Registar Categoria - permite o registo de novas categorias;\n" +
                                  " 2 - Consultar Categoria - permite consultar, editar e eliminar categorias;\n" +

                                  " 0 - Voltar ao menu principal;\n");

                string aux = Console.ReadLine();
                if (int.TryParse(aux, out opcao))
                {
                    Console.WriteLine("\n");
                    switch (opcao)
                    {
                        case 1:
                            Console.Clear();
                            registarCategoria();
                            break;
                        case 2:
                            Console.Clear();
                            menuConsultarCategorias();
                            break;
                        case 0:
                            Console.Clear();
                            MenuPrincipal.menuPrincipal();
                            break;
                        default:
                            Console.Clear();
                            Console.WriteLine("Introduza a uma opcao valida. [0-2]\n");
                            break;
                    }
                }
                else
                {
                    opcao = -1;
                    Console.Clear();
                    Console.WriteLine("Por favor introduza apenas numeros.\n");
                }
            } while (opcao != 0);
        }

        private static void registarCategoria()
        {
            BTO.Categoria categoria = new BTO.Categoria();
            try
            {
                Console.Write("Descricao da categoria: ");
                string descricao = Console.ReadLine();

                Console.WriteLine("\nA escrever na base de dados. . . \n");

                categoria.descricao = descricao;
                
                BLLCategoria novaCategoria = new BLLCategoria();

                novaCategoria.insert(categoria);

                Console.WriteLine("Nova categoria registada com sucesso!\n");
            }
            catch (DescricaoCategoriaException e)
            {
                Console.WriteLine(e.Message + "\n");
                Console.Write("Pretende introduzir novamente? (y/n)\n ");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.Write("Introduza novamente a descricao:\n ");
                    string descricao = Console.ReadLine();
                    categoria.descricao = descricao;

                    Console.WriteLine("\nA escrever na base de dados. . . \n");
                    registarCategoria(categoria);

                }
                else
                {
                    menuCategoriasAlojamento();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + "\n");
            }

            menuCategoriasAlojamento();
        }

        private static void registarCategoria(BTO.Categoria categoria)
        {
            try
            {
                BLLCategoria novaCategoria = new BLLCategoria();
                novaCategoria.insert(categoria);
            }
            catch (DescricaoCategoriaException e)
            {
                Console.WriteLine(e.Message + "\n");
                Console.Write("Pretende introduzir novamente? (y/n)\n ");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.Write("Introduza novamente a descricao:\n ");
                    string descricao = Console.ReadLine();
                    categoria.descricao = descricao;
                    registarCategoria(categoria);
                    Console.WriteLine("Nova categoria registada com sucesso!\n");
                }
                else
                {
                    menuCategoriasAlojamento();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + "\n");
            }

            menuCategoriasAlojamento();
        }

        private static void menuConsultarCategorias()
        {
            do
            {
                opcao = 0;
                Console.WriteLine("Menu de consulta e gestao de categorias de alojamento, \nescolha uma das operacoes:\n\n");
                Console.WriteLine(" 1 - Listar todas as categorias registadas;\n" +
                                  " 2 - Listar por id;\n" +
                                  " 3 - Listar por descricao;\n" +
                                  " 0 - Voltar ao Menu Categorias Alojamento;\n");

                string aux = Console.ReadLine();
                if (int.TryParse(aux, out opcao))
                {
                    Console.WriteLine("\n");
                    switch (opcao)
                    {
                        case 1:
                            Console.Clear();
                            listarCategorias();
                            break;
                        case 2:
                            Console.Clear();
                            listarCategoriasPorId();
                            break;
                        case 3:
                            Console.Clear();
                            listarCategoriasPorDescricao();
                            break;
                        case 0:
                            Console.Clear();
                            menuCategoriasAlojamento();
                            break;
                        default:
                            Console.WriteLine("Introduza a uma opcao valida. [0-3]\n");
                            break;
                    }
                }
                else
                {
                    opcao = -1;
                    Console.Clear();
                    Console.WriteLine("Por favor introduza apenas numeros.\n");
                }
            } while (opcao != 0);
        }

        private static void listarCategorias()
        {

            Console.WriteLine("Lista das categorias registadas: \n\n");
            Console.WriteLine("A carregar lista . . .\n");
            BLLCategoria categoria = new BLLCategoria();
            try
            {
                List<BTO.Categoria> listCategorias = categoria.list();
                Console.WriteLine("Lista ok!\n\n");

                int counter = 1;
                foreach (BTO.Categoria cate in listCategorias)
                {
                    Console.WriteLine("\n\n" + counter + ": ");
                    Console.WriteLine(cate);
                    counter++;
                }
            }
            catch (NotFoundCategoriaException ex)
            {
                Console.WriteLine(ex.Message + "\n\n");
            }
            Console.WriteLine("\n\nQuando desejar pressione \"enter\" para voltar ao menu de gestao de categorias de alojamento.");

            //Listener para averiguar se o utilizador pressiona enter
            ConsoleKeyInfo keyHit = new ConsoleKeyInfo();
            keyHit = Console.ReadKey(true);

            if (keyHit.Key == ConsoleKey.Enter) { Console.Clear(); menuConsultarCategorias (); }
        }

        private static void listarCategoriasPorId()
        {

            Console.WriteLine("Apos seleccionar a categoria, vai poder efectuar operacoes sobre a mesma.\n");
            Console.Write("Introduza o id da categoria que procura: ");
            int id = -1;
            String aux = Console.ReadLine();

            if (int.TryParse(aux, out id))
            {
                Console.WriteLine("\nA procurar . . .\n");
                BLLCategoria categoria = new BLLCategoria();

                try
                {
                    Console.WriteLine(categoria.getByID(id));
                    Console.WriteLine("\n");
                    operarSobreCategoria(categoria.getByID(id));
                    menuConsultarCategorias();
                }
                catch (NotFoundCategoriaException ex)
                {

                    Console.WriteLine("\n" + ex.Message + " Por favor verifique o id da categoria e introduza novamente.\n\n");
                    Console.WriteLine("Prefere sair para o menu anterior? (y/n)");
                    string resposta = Console.ReadLine();
                    if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                    {
                        Console.Clear();
                        menuConsultarCategorias();
                    }
                    else
                    {
                        Console.Clear();
                        listarCategoriasPorId();
                    }
                }

            }
            else
            {
                Console.WriteLine("\nAtencao o id apenas pode conter numeros inteiros.\n");
                Console.WriteLine("\nPor favor volte a introduzir o id.\n\n\n");
                listarCategoriasPorId();
            }

        }

        private static void listarCategoriasPorDescricao()
        {

            Console.WriteLine("Apos seleccionar a categoria, vai poder efectuar operacoes sobre a mesma.\n");
            Console.Write("Introduza a descricao da categoria que procura: ");
            String descricao = Console.ReadLine();
            Console.WriteLine("\nA procurar . . .\n");
            BLLCategoria categoria = new BLLCategoria();

            try
            {
                Console.WriteLine(categoria.getByDescricao(descricao));
                Console.WriteLine("\n");
                operarSobreCategoria(categoria.getByDescricao(descricao));
                menuConsultarCategorias();
            }
            catch (NotFoundCategoriaException ex)
            {

                Console.WriteLine("\n" + ex.Message + " Por favor verifique a descricao da categoria e introduza novamente.\n\n");
                Console.WriteLine("Prefere sair para o menu anterior? (y/n)");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.Clear();
                    menuConsultarCategorias();
                }
                else
                {
                    Console.Clear();
                    listarCategoriasPorDescricao();
                }
            }
        }

        private static void operarSobreCategoria(BTO.Categoria categoria)
        {
            do
            {
                opcao = 0;
                Console.WriteLine("Menu de gestao da categoria " + categoria.descricao + ", escolha uma das operacoes:\n\n");
                Console.WriteLine(" 1 - Editar informacoes da categoria;\n" +
                                  " 2 - Eliminar a categoria;\n" +
                                  " 0 - Voltar ao menu de consulta e gestao;\n");

                string aux = Console.ReadLine();
                if (int.TryParse(aux, out opcao))
                {
                    Console.WriteLine("\n");
                    switch (opcao)
                    {
                        case 1:
                            Console.Clear();
                            actualizarCategoria(categoria);
                            break;
                        case 2:
                            Console.Clear();
                            eliminarCategoria(categoria);
                            break;
                        case 0:
                            Console.Clear();
                            menuConsultarCategorias();
                            break;
                        default:
                            Console.WriteLine("Introduza a uma opcao valida. [0-2]\n");
                            break;
                    }
                }
                else
                {
                    opcao = -1;
                    Console.Clear();
                    Console.WriteLine("Por favor introduza apenas numeros.\n");
                }
            } while (opcao != 0);
        }

        private static void actualizarCategoria(BTO.Categoria toUpdate)
        {
            Console.WriteLine("Edicao e actualizacao dos dados da categoria " + toUpdate.descricao + ".\n");
            Console.WriteLine("A esquerda é fornecida a informacao actual;");
            Console.WriteLine("Do lado direito pode editar a informacao, ou manter a antiga.\n\n");

            BLLCategoria categoria = new BLLCategoria();
            BTO.Categoria oldCategoria = toUpdate;
            BTO.Categoria newCategoria = new BTO.Categoria();

            newCategoria.IDCategoria = oldCategoria.IDCategoria;

            Console.Write("Descricao (" + oldCategoria.descricao + "): ");
            string newDescricao = Console.ReadLine();
            if (newDescricao == "")
                newCategoria.descricao = oldCategoria.descricao;
            else
                newCategoria.descricao = newDescricao;

            try
            {
                Console.WriteLine("Tem a certeza que pretende alterar o registo da categoria " + oldCategoria.descricao + "? (y/n)");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.WriteLine("\nA alterar . . .\n");
                    categoria.update(newCategoria);
                    Console.WriteLine("Dados da categoria alterados com sucesso!\n\n");
                    operarSobreCategoria(newCategoria);
                } 
            }
            catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(newCategoria); operarSobreCategoria(oldCategoria); }
            operarSobreCategoria(oldCategoria);
        }

        private static void eliminarCategoria(BTO.Categoria toDelete)
        {
            Console.WriteLine("Tem a certeza que pretende eliminar o registo da categoria " + toDelete.descricao + "? (y/n)");
            string resposta = Console.ReadLine();
            if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
            {
                Console.WriteLine("\nA eliminar . . .\n");
                BLLCategoria categoria = new BLLCategoria();
                categoria.delete(toDelete.IDCategoria);
                Console.WriteLine("Categoria eliminada com sucesso!\n\n");
                menuConsultarCategorias();
            }
            operarSobreCategoria(toDelete);
        }
    }
}
